/*
 *  bitstream.c
 *  oE6
 *
 *  Created by Tony Million on 13/12/2008.
 *  Copyright 2008 Tony Million. All rights reserved.
 *
 */

#include "bitstream.h"

#define MIN(a,b) (((a) < (b)) ? (a) : (b))

void bsinit(bitstream * bs, unsigned char * data, unsigned long datalength)
{
	bs->data		= data;
	bs->datalength	= datalength;
	bs->bitoffset	= 0;
}

unsigned long bsgetbits(bitstream * bs, unsigned long numbits)
{
	unsigned long rval;
	int pos;
	
	if(numbits == 0)
		return 0;
	
	pos = (unsigned long)(bs->bitoffset >> 3);
	if(pos>bs->datalength)
		return 0;
	
	rval =	(unsigned long)bs->data[pos]	<< 24 |
			(unsigned long)bs->data[pos+1]	<< 16 |
			(unsigned long)bs->data[pos+2]	<< 8 |
			(unsigned long)bs->data[pos+3];
	
	rval <<= bs->bitoffset & 7;
	rval >>= 32 - numbits;
	
	bs->bitoffset += numbits;
	
	return rval;	
}

void bsdismiss(bitstream * bs, unsigned long numbits)
{
	bs->bitoffset += numbits;
}

void bsrewind(bitstream * bs, unsigned long numbits)
{
	// either rewind to the beginning, or back the number of bits requested!
	bs->bitoffset -= MIN(numbits, bs->bitoffset);
}